package cn.iocoder.yudao.module.eval.service.rule;

import cn.iocoder.yudao.module.eval.dal.dataobject.candidate.EvalCandidateInfoDO;
import cn.iocoder.yudao.module.eval.dal.dataobject.plan.EvalPlanDO;
import cn.iocoder.yudao.module.eval.dal.dataobject.score.EvalScoreRecordDO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.Period;
import java.util.*;

/**
 * 评价业务规则 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Slf4j
public class EvalBusinessRuleServiceImpl implements EvalBusinessRuleService {

    @Override
    public Object validateApplicationConditions(EvalCandidateInfoDO candidateInfo, EvalPlanDO plan) {
        Map<String, Object> result = new HashMap<>();
        List<String> errors = new ArrayList<>();
        List<String> warnings = new ArrayList<>();

        // 年龄验证
        if (candidateInfo.getBirthDate() != null) {
            int age = Period.between(candidateInfo.getBirthDate(), LocalDate.now()).getYears();
            if (age < 16) {
                errors.add("申报人员年龄不能小于16岁");
            }
            if (age > 65) {
                warnings.add("申报人员年龄超过65岁，请确认是否符合特殊规定");
            }
        }

        // 学历验证（根据申报等级）
        String appliedLevel = candidateInfo.getAppliedLevel();
        if ("一级".equals(appliedLevel) || "二级".equals(appliedLevel)) {
            // 高级技师和技师通常需要更高学历要求
            warnings.add("申报高级等级，请确认学历和工作经验是否满足要求");
        }

        // 工作经验验证
        if (candidateInfo.getWorkYears() != null) {
            int workYears = candidateInfo.getWorkYears().intValue();
            Map<String, Integer> minWorkYears = getMinWorkYearsRequirement();
            Integer requiredYears = minWorkYears.get(appliedLevel);
            if (requiredYears != null && workYears < requiredYears) {
                errors.add(String.format("申报%s等级需要至少%d年工作经验，当前为%d年", 
                    appliedLevel, requiredYears, workYears));
            }
        }

        // 职业匹配验证
        if (!candidateInfo.getAppliedProfession().equals(plan.getProfessionName())) {
            errors.add("申报职业与计划职业不匹配");
        }

        // 等级匹配验证
        if (plan.getApplicableLevels() != null && 
            !plan.getApplicableLevels().contains(candidateInfo.getAppliedLevel())) {
            errors.add("申报等级不在计划适用等级范围内");
        }

        result.put("isValid", errors.isEmpty());
        result.put("errors", errors);
        result.put("warnings", warnings);
        return result;
    }

    @Override
    public Object validateQualificationConditions(EvalCandidateInfoDO candidateInfo) {
        Map<String, Object> result = new HashMap<>();
        List<String> errors = new ArrayList<>();

        // 基本信息完整性检查
        if (candidateInfo.getName() == null || candidateInfo.getName().trim().isEmpty()) {
            errors.add("姓名不能为空");
        }
        if (candidateInfo.getIdNumber() == null || candidateInfo.getIdNumber().trim().isEmpty()) {
            errors.add("身份证号不能为空");
        }
        if (candidateInfo.getMobile() == null || candidateInfo.getMobile().trim().isEmpty()) {
            errors.add("手机号不能为空");
        }

        // 身份证号格式验证
        if (candidateInfo.getIdNumber() != null && !isValidIdNumber(candidateInfo.getIdNumber())) {
            errors.add("身份证号格式不正确");
        }

        // 手机号格式验证
        if (candidateInfo.getMobile() != null && !isValidMobile(candidateInfo.getMobile())) {
            errors.add("手机号格式不正确");
        }

        result.put("isValid", errors.isEmpty());
        result.put("errors", errors);
        return result;
    }

    @Override
    public Object calculateComprehensiveScore(List<EvalScoreRecordDO> scoreRecords, Map<String, Object> calculationRules) {
        Map<String, Object> result = new HashMap<>();
        
        if (scoreRecords == null || scoreRecords.isEmpty()) {
            result.put("totalScore", BigDecimal.ZERO);
            result.put("weightedScore", BigDecimal.ZERO);
            result.put("subjectScores", new HashMap<>());
            return result;
        }

        BigDecimal totalScore = BigDecimal.ZERO;
        BigDecimal weightedScore = BigDecimal.ZERO;
        Map<String, BigDecimal> subjectScores = new HashMap<>();

        // 计算各科目成绩
        for (EvalScoreRecordDO record : scoreRecords) {
            if (record.getTotalScore() != null) {
                String subjectKey = "subject_" + record.getSubjectId();
                subjectScores.put(subjectKey, record.getTotalScore());
                
                // 累加总分（简单平均）
                totalScore = totalScore.add(record.getTotalScore());
                
                // 加权计算（如果有权重配置）
                BigDecimal weight = getSubjectWeight(record.getSubjectId(), calculationRules);
                weightedScore = weightedScore.add(record.getTotalScore().multiply(weight));
            }
        }

        // 计算平均分
        if (!scoreRecords.isEmpty()) {
            totalScore = totalScore.divide(BigDecimal.valueOf(scoreRecords.size()), 2, RoundingMode.HALF_UP);
        }

        result.put("totalScore", totalScore);
        result.put("weightedScore", weightedScore);
        result.put("subjectScores", subjectScores);
        return result;
    }

    @Override
    public boolean isQualified(BigDecimal totalScore, Map<String, BigDecimal> subjectScores, Map<String, Object> passingRules) {
        // 总分合格线检查
        BigDecimal passingScore = new BigDecimal("60"); // 默认60分合格
        if (passingRules != null && passingRules.containsKey("passingScore")) {
            passingScore = new BigDecimal(passingRules.get("passingScore").toString());
        }
        
        if (totalScore.compareTo(passingScore) < 0) {
            return false;
        }

        // 单科合格线检查
        if (passingRules != null && passingRules.containsKey("subjectPassingScore")) {
            BigDecimal subjectPassingScore = new BigDecimal(passingRules.get("subjectPassingScore").toString());
            for (BigDecimal score : subjectScores.values()) {
                if (score.compareTo(subjectPassingScore) < 0) {
                    return false;
                }
            }
        }

        return true;
    }

    @Override
    public String calculateGradeLevel(BigDecimal totalScore, Map<String, Object> gradingRules) {
        // 默认等级划分
        if (totalScore.compareTo(new BigDecimal("90")) >= 0) {
            return "优秀";
        } else if (totalScore.compareTo(new BigDecimal("80")) >= 0) {
            return "良好";
        } else if (totalScore.compareTo(new BigDecimal("60")) >= 0) {
            return "合格";
        } else {
            return "不合格";
        }
    }

    @Override
    public Object validateEvaluatorQualification(Long evaluatorId, String professionCode, String skillLevel) {
        Map<String, Object> result = new HashMap<>();
        List<String> errors = new ArrayList<>();

        // TODO: 实际实现中需要查询考评员资质表
        // 这里提供示例逻辑
        
        result.put("isValid", errors.isEmpty());
        result.put("errors", errors);
        return result;
    }

    @Override
    public Object validateScoreDataIntegrity(EvalScoreRecordDO scoreRecord) {
        Map<String, Object> result = new HashMap<>();
        List<String> errors = new ArrayList<>();

        if (scoreRecord.getTotalScore() == null) {
            errors.add("总分不能为空");
        }
        if (scoreRecord.getMaxScore() == null) {
            errors.add("满分不能为空");
        }
        if (scoreRecord.getTotalScore() != null && scoreRecord.getMaxScore() != null) {
            if (scoreRecord.getTotalScore().compareTo(scoreRecord.getMaxScore()) > 0) {
                errors.add("总分不能超过满分");
            }
            if (scoreRecord.getTotalScore().compareTo(BigDecimal.ZERO) < 0) {
                errors.add("总分不能为负数");
            }
        }

        result.put("isValid", errors.isEmpty());
        result.put("errors", errors);
        return result;
    }

    @Override
    public Object checkTimeConflict(Long planId, java.time.LocalDateTime startTime, java.time.LocalDateTime endTime) {
        Map<String, Object> result = new HashMap<>();
        List<String> conflicts = new ArrayList<>();

        // TODO: 实际实现中需要查询数据库检查时间冲突
        
        result.put("hasConflict", !conflicts.isEmpty());
        result.put("conflicts", conflicts);
        return result;
    }

    @Override
    public Object validatePersonnelAssignmentRules(Long planId, Long userId, Integer personType) {
        Map<String, Object> result = new HashMap<>();
        List<String> errors = new ArrayList<>();

        // TODO: 实现人员分配规则验证
        
        result.put("isValid", errors.isEmpty());
        result.put("errors", errors);
        return result;
    }

    @Override
    public BigDecimal calculateAttendanceScore(List<Object> attendanceRecords, Map<String, Object> attendanceRules) {
        // TODO: 实现考勤得分计算
        return new BigDecimal("100");
    }

    @Override
    public Object validateMaterialCompleteness(Long candidateId, List<String> requiredMaterials) {
        Map<String, Object> result = new HashMap<>();
        List<String> missingMaterials = new ArrayList<>();

        // TODO: 实际实现中需要查询材料表
        
        result.put("isComplete", missingMaterials.isEmpty());
        result.put("missingMaterials", missingMaterials);
        return result;
    }

    @Override
    public Object checkPlanCapacity(Long planId, Integer additionalCount) {
        Map<String, Object> result = new HashMap<>();
        
        // TODO: 实际实现中需要查询计划和当前人数
        
        result.put("canAccommodate", true);
        result.put("currentCount", 0);
        result.put("maxCapacity", 100);
        result.put("availableSlots", 100);
        return result;
    }

    // 辅助方法
    private Map<String, Integer> getMinWorkYearsRequirement() {
        Map<String, Integer> requirements = new HashMap<>();
        requirements.put("五级", 0);
        requirements.put("四级", 2);
        requirements.put("三级", 4);
        requirements.put("二级", 6);
        requirements.put("一级", 8);
        return requirements;
    }

    private BigDecimal getSubjectWeight(Long subjectId, Map<String, Object> calculationRules) {
        // TODO: 从计算规则中获取科目权重
        return new BigDecimal("1.0");
    }

    private boolean isValidIdNumber(String idNumber) {
        // 简单的身份证号格式验证
        return idNumber != null && idNumber.matches("^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$");
    }

    private boolean isValidMobile(String mobile) {
        // 简单的手机号格式验证
        return mobile != null && mobile.matches("^1[3-9]\\d{9}$");
    }

}
